// ====== 简单工具函数 ======
function euclideanDistance(a, b) {
  return Math.sqrt(a.reduce((sum, val, i) => sum + (val - b[i]) ** 2, 0));
}

// ====== K-means 聚类 ======
export function kmeans(data, k = 3, maxIter = 100) {
  // 随机初始化簇中心
  let centroids = data.slice(0, k).map(v => [...v]);

  let assignments = new Array(data.length).fill(-1);

  for (let iter = 0; iter < maxIter; iter++) {
    // 分配样本到最近的簇
    assignments = data.map(point => {
      let distances = centroids.map(c => euclideanDistance(point, c));
      return distances.indexOf(Math.min(...distances));
    });

    // 更新簇中心
    let newCentroids = Array.from({ length: k }, () => Array(data[0].length).fill(0));
    let counts = Array(k).fill(0);

    data.forEach((point, i) => {
      const cluster = assignments[i];
      counts[cluster]++;
      point.forEach((val, j) => {
        newCentroids[cluster][j] += val;
      });
    });

    newCentroids = newCentroids.map((c, i) =>
      c.map(val => (counts[i] ? val / counts[i] : val))
    );

    // 检查是否收敛
    if (JSON.stringify(newCentroids) === JSON.stringify(centroids)) break;
    centroids = newCentroids;
  }

  return { centroids, assignments };
}

// ====== 特征编码 ======
export function encodePerson(person ) {
  const hobbyWords = ["喝酒", "舞剑", "作诗", "绘画", "弹琴", "数学", "物理", "炼丹", "游历", "下棋", "写字", "读书", "写信"];
  const occupationWords = ["文学家", "科学家", "艺术家", "音乐家", "哲学家", "医生", "政治家", "军事家", "商人"];
  const personalityWords = ["浪漫", "豪爽", "亲切", "和蔼", "冷静", "理智", "豪放", "直率", "细腻", "温柔", "睿智", "幽默", "沉稳", "坚毅"];

  const minMax = {age:[20,60], height:[150,200]}

  const features = [];

  // 年龄归一化
  const age = Number(person.age);
  features.push((age - minMax.age[0]) / (minMax.age[1] - minMax.age[0]));

  // 身高归一化
  const height = Number(person.height.replace("cm",""));
  features.push((height - minMax.height[0]) / (minMax.height[1] - minMax.height[0]));

  // 爱好 one-hot
  hobbyWords.forEach(h => {
    features.push(person.hobby.includes(h) ? 1 : 0);
  });

  // 职业 one-hot
  occupationWords.forEach(o => {
    features.push(person.occupation === o ? 1 : 0);
  });

  // 性格 one-hot
  personalityWords.forEach(p => {
    features.push(person.personality.includes(p) ? 1 : 0);
  });

  return features;
}




